----------------------------------------------------------------
-- Global Variables
----------------------------------------------------------------

EA_Window_PublicQuestTracker = {}

EA_Window_PublicQuestTracker.EMPTY_SIZE = { x=600, y=200 } -- Used to provide a size guide for the layout editor.

EA_Window_PublicQuestTracker.NUM_OBJECTIVES = 2
EA_Window_PublicQuestTracker.NUM_QUESTS = 3
EA_Window_PublicQuestTracker.NUM_CONDITION_COUNTERS = 5

EA_Window_PublicQuestTracker.WIDTH = 600
EA_Window_PublicQuestTracker.QUEST_WITH_TIMER_WIDTH = 525
EA_Window_PublicQuestTracker.CONDITION_NAME_WIDTH = 530

EA_Window_PublicQuestTracker.currentData = {}


----------------------------------------------------------------
-- Local Variables
----------------------------------------------------------------

local CompleteCounterColor      = DefaultColor.TEAL
local IncompleteCounterColor    = DefaultColor.WHITE
local CompleteQuestTitleColor   = CompleteCounterColor 
local IncompleteQuestTitleColor = IncompleteCounterColor

----------------------------------------------------------------
-- Local functions
----------------------------------------------------------------
local function DisplayObjectiveOutOfRangeError(index)
    if (index)
    then
        ERROR(L"Active objective #"..index..L" updated, Public Quest Tracker only supports two objectives")
    else
        ERROR(L"nil active objective updated, what's that mean?")
    end
end

----------------------------------------------------------------
-- EA_Window_PublicQuestTracker Functions
----------------------------------------------------------------
-- OnInitialize Handler
function EA_Window_PublicQuestTracker.Initialize()

    LayoutEditor.RegisterWindow( "EA_Window_PublicQuestTracker",
                                GetStringFromTable( "HUDStrings", StringTables.HUD.LABEL_HUD_EDIT_PUBLIC_QUEST_TRACKER_WINDOW_NAME ),
                                GetStringFromTable( "HUDStrings", StringTables.HUD.LABEL_HUD_EDIT_PUBLIC_QUEST_TRACKER_WINDOW_DESC ),
                                false, false,
                                false, nil,
                                { "topleft", "top", "topright" } )
                                

    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_ADDED,   "EA_Window_PublicQuestTracker.OnQuestAdded")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_UPDATED, "EA_Window_PublicQuestTracker.OnQuestUpdated")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_REMOVED, "EA_Window_PublicQuestTracker.OnQuestRemoved")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_CONDITION_UPDATED, "EA_Window_PublicQuestTracker.OnQuestConditionUpdated")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_COMPLETED, "EA_Window_PublicQuestTracker.OnQuestCompleted")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_FAILED, "EA_Window_PublicQuestTracker.OnQuestFailed")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_RESETTING, "EA_Window_PublicQuestTracker.OnQuestResetting")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_OPTOUT, "EA_Window_PublicQuestTracker.OnQuestOptOut")
            
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PUBLIC_QUEST_CHANGED_STATE,   "EA_Window_PublicQuestTracker.OnQuestStateChanged")
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PLAYER_ZONE_CHANGED,          "EA_Window_PublicQuestTracker.OnZoneChange")

    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PLAYER_AREA_CHANGED,          "EA_Window_PublicQuestTracker.OnAreaChange" )
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PLAYER_INFLUENCE_UPDATED,     "EA_Window_PublicQuestTracker.OnPlayerInfluenceUpdated" )
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.LOADING_END,                  "EA_Window_PublicQuestTracker.UpdateInfluenceBar" )
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.INTERFACE_RELOADED,           "EA_Window_PublicQuestTracker.Refresh" )
    WindowRegisterEventHandler( "EA_Window_PublicQuestTracker", SystemData.Events.PLAYER_INFLUENCE_RANK_UPDATED,"EA_Window_PublicQuestTracker.OnRankUp" )
    
    EA_Window_PublicQuestTracker.UpdateFullList()
    EA_Window_PublicQuestTracker.UpdateInfluenceBar()
    EA_Window_PublicQuestTracker.UpdateLocation()
    
    StatusBarSetMaximumValue("EA_Window_PublicQuestTrackerInfluenceBarFill", 100 ) -- Maximum of 100%

end

function EA_Window_PublicQuestTracker.InitializeLayout()
    EA_Window_PublicQuestTracker.UpdateMainWindowSize()
end

-- OnUpdate Handler
function EA_Window_PublicQuestTracker.Update( timePassed )
    -- Update the timers
    EA_Window_PublicQuestTracker.UpdateQuestTimer()
end

-- OnShutdown Handler
function EA_Window_PublicQuestTracker.Shutdown()

end

function EA_Window_PublicQuestTracker.Refresh()
    EA_Window_PublicQuestTracker.UpdateInfluenceBar()
end

function EA_Window_PublicQuestTracker.OnRankUp()
    Sound.Play(Sound.INFLUENCE_RANK_UP)
end


----------------------------------------------------------------
-- Pairing and Chapter text
----------------------------------------------------------------
function EA_Window_PublicQuestTracker.UpdateLocation()
    local raceLocation = StringUtils.GetFriendlyRaceForCurrentPairing( zonePairing, true )
    LabelSetText("EA_Window_PublicQuestTrackerLocationPairingLabel", raceLocation)
    
    local influenceID = EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID()
    if ((influenceID ~= nil) and (influenceID > 0))
    then
        local chapterName = GetChapterShortName( influenceID )
        LabelSetText("EA_Window_PublicQuestTrackerLocationChapterLabel", chapterName)
    else
        LabelSetText("EA_Window_PublicQuestTrackerLocationChapterLabel", L"")
    end
end

----------------------------------------------------------------
-- Quests
----------------------------------------------------------------
function EA_Window_PublicQuestTracker.OnQuestAdded() 
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    local index = GameData.ActiveObjectives.updatedObjectiveIndex    
    
    -- DEBUG(L"EA_Window_PublicQuestTracker.OnQuestAdded: index="..index )

    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end
    
    -- Add the data
    EA_Window_PublicQuestTracker.currentData[index] = { objectiveId=DataUtils.activeObjectivesData[index].id } 
    
    -- Update the Window to Include the new objective       
    EA_Window_PublicQuestTracker.UpdateTracker( index )      
    EA_Window_PublicQuestTracker.UpdateQuestVisibility()     
    
    -- Sound
    Sound.Play( Sound.PUBLIC_QUEST_ADDED )
    
end

function EA_Window_PublicQuestTracker.OnQuestResetting()
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    -- DEBUG(L"EA_Window_PublicQuestTracker.OnQuestResetting" )

    local index = GameData.ActiveObjectives.updatedObjectiveIndex

    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end
    
    local showing = WindowGetShowing( "EA_Window_PublicQuestTracker" )
    
    if ( showing == false )
    then
        -- Sound
        Sound.Play( Sound.PUBLIC_QUEST_CYCLING )
    end
    
end

function EA_Window_PublicQuestTracker.OnQuestUpdated() 
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    -- DEBUG(L"EA_Window_PublicQuestTracker.OnQuestUpdated" )

    local index = GameData.ActiveObjectives.updatedObjectiveIndex

    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end
    
    -- Update the Window to Include the new objective       
    EA_Window_PublicQuestTracker.UpdateTracker( index )
    EA_Window_PublicQuestTracker.UpdateMainWindowSize()
end


function EA_Window_PublicQuestTracker.OnQuestRemoved()
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    
    local index = GameData.ActiveObjectives.updatedObjectiveIndex
    -- DEBUG(L"EA_Window_PublicQuestTracker.OnQuestRemoved() index = "..index)

    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end
           
    -- Slide all of the other data up on the window
    for objective = index, EA_Window_PublicQuestTracker.NUM_OBJECTIVES - 1
    do
        EA_Window_PublicQuestTracker.currentData[objective] = EA_Window_PublicQuestTracker.currentData[objective+1]
    end
    EA_Window_PublicQuestTracker.currentData[EA_Window_PublicQuestTracker.NUM_OBJECTIVES] = nil
    
    -- Update the windows
    for objective = index, EA_Window_PublicQuestTracker.NUM_OBJECTIVES
    do
        EA_Window_PublicQuestTracker.UpdateTracker( objective )
    end
    
    EA_Window_PublicQuestTracker.UpdateQuestVisibility()
    
end

function EA_Window_PublicQuestTracker.OnQuestCompleted()
    -- DEBUG(L"EA_Window_PublicQuestTracker.OnQuestCompleted()")
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    -- Sound
    Sound.Play( Sound.PUBLIC_QUEST_COMPLETED )
end

function EA_Window_PublicQuestTracker.OnQuestFailed()
    -- DEBUG(L" **EA_Window_PublicQuestTracker.OnQuestFailed" )
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    -- Sound
    Sound.Play( Sound.PUBLIC_QUEST_FAILED )
end

function EA_Window_PublicQuestTracker.OnQuestConditionUpdated()

    -- DEBUG(L" **EA_Window_PublicQuestTracker.OnQuestConditionUpdated" )
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    local objective  = GameData.ActiveObjectives.updatedObjectiveIndex
    local questIndex = GameData.ActiveObjectives.updatedQuestIndex
    local condition  = GameData.ActiveObjectives.updatedQuestConditionIndex
    
    if (not ((objective == 1) or (objective == 2)))
    then
        DisplayObjectiveOutOfRangeError(objective)
        return -- This should never happen
    end
    
    local questData = DataUtils.activeObjectivesData[objective].Quest[questIndex]

    -- Update only the Condtion Counters
    local questWindowString = "EA_Window_PublicQuestTrackerObjective"..objective.."Quest"..questIndex
    
    for index, data in pairs(questData.conditions)
    do
    
        local conditionName = data.name
        local curCounter    = data.curCounter
        local maxCounter    = data.maxCounter
                
        local counterLabel = questWindowString.."DataCondition"..index.."Counter"
        local counterName  = questWindowString.."DataCondition"..index.."Name"

        -- Only show the conditions if conditionName is not empty
        if( conditionName ~= L"" )
        then
        -- DEBUG(L"Made it through 06 - conditions")
                  
            if( maxCounter > 0 )
            then
                LabelSetText( counterLabel, L""..curCounter..L"/"..maxCounter )

                if( curCounter == maxCounter)
                then
                    LabelSetTextColor(counterLabel, CompleteCounterColor.r, CompleteCounterColor.g, CompleteCounterColor.b )
                    LabelSetTextColor(counterName,  CompleteCounterColor.r, CompleteCounterColor.g, CompleteCounterColor.b )
                else
                    LabelSetTextColor(counterLabel, IncompleteCounterColor.r, IncompleteCounterColor.g, IncompleteCounterColor.b)
                    LabelSetTextColor(counterName,  IncompleteCounterColor.r, IncompleteCounterColor.g, IncompleteCounterColor.b)
                end         
                
                --DEBUG(L"    Condition #"..condition..L": "..curCounter..L" of "..maxCounter..L" counters.")
            else
                LabelSetText( counterLabel, L"" )
            end
            
        end   
    end
    
end


function EA_Window_PublicQuestTracker.OnQuestStateChanged()
    DataUtils.activeObjectivesData = GetActiveObjectivesData()
    -- DEBUG(L" **EA_Window_PublicQuestTracker.OnQuestStateChanged" )

    local index = GameData.ActiveObjectives.updatedObjectiveIndex

    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end

    -- Update the Quest Data 
    EA_Window_PublicQuestTracker.UpdateTracker( index )
    EA_Window_PublicQuestTracker.UpdateMainWindowSize()
end


function EA_Window_PublicQuestTracker.UpdateQuestTimer()

    for objectiveIndex = 1, EA_Window_PublicQuestTracker.NUM_OBJECTIVES
    do
        for questIndex = 1, EA_Window_PublicQuestTracker.NUM_QUESTS
        do
            local questWindowString = "EA_Window_PublicQuestTrackerObjective"..objectiveIndex.."Quest"..questIndex
            
            if (DataUtils.activeObjectivesData == nil) or
               (DataUtils.activeObjectivesData[objectiveIndex] == nil) or
               (DataUtils.activeObjectivesData[objectiveIndex].Quest == nil) or
               (DataUtils.activeObjectivesData[objectiveIndex].Quest[questIndex] == nil)
            then
                LabelSetText( questWindowString.."TimerValue", L"" )      
                WindowSetShowing( questWindowString.."ClockImage", false )
            else
                -- Timer (only show timer at all if this is the first quest in the first objective)
                if( DataUtils.activeObjectivesData[objectiveIndex].Quest[questIndex].maxTimer ~= 0 and
                    DataUtils.activeObjectivesData[objectiveIndex].Quest[questIndex].maxTimer ~= nil )
                then
                    -- DEBUG(L"Made it through 05 - timer")
                    local timeLeft = DataUtils.activeObjectivesData[objectiveIndex].Quest[questIndex].timeLeft
                    local text = TimeUtils.FormatClock(timeLeft)
                    LabelSetText( questWindowString.."TimerValue", text )
                    WindowSetShowing( questWindowString.."ClockImage", true )
                else            
                    LabelSetText( questWindowString.."TimerValue", L"" )      
                    WindowSetShowing( questWindowString.."ClockImage", false )
                end
            end
        end
    end
end

-- This is only called on initialization to populate the window without any state changing animations
function EA_Window_PublicQuestTracker.UpdateFullList()

    -- DEBUG(L"EA_Window_PublicQuestTracker.UpdateFullList()")
    --DataUtils.activeObjectivesData = GetActiveObjectivesData()
    local objectiveCount = 0
    
    for objective = 1, EA_Window_PublicQuestTracker.NUM_OBJECTIVES
    do
        local isObjectiveValid = false
        local objectiveWindowString = "EA_Window_PublicQuestTrackerObjective"..objective

        for questIndex = 1, EA_Window_PublicQuestTracker.NUM_QUESTS
        do
            local isQuestValid = false

            if ( DataUtils.activeObjectivesData ~= nil )
            then
                if ( DataUtils.activeObjectivesData[objective] ~= nil )
                then
                    if( DataUtils.activeObjectivesData[objective].Quest[questIndex] ~= nil )
                    then
                        isQuestValid = DataUtils.activeObjectivesData[objective].Quest[questIndex].name ~= L"" and
                                       DataUtils.activeObjectivesData[objective].Quest[questIndex].name ~= nil
                    end
                end
            end
    
            WindowSetShowing( objectiveWindowString.."Quest"..questIndex, isQuestValid )
            
            isObjectiveValid = isObjectiveValid or isQuestValid
        end
        
        if( isObjectiveValid )
        then
            --DEBUG(L"Public Quest #"..objective..L" = "..GameData.ActiveObjectives[objective].name )
            --DEBUG(L"  Objective #"..objective..L" has data.")
            EA_Window_PublicQuestTracker.currentData[objective] = { objectiveId=DataUtils.activeObjectivesData[objective].id }
            WindowSetShowing( objectiveWindowString, true )
            EA_Window_PublicQuestTracker.UpdateTracker( objective )
            objectiveCount = objectiveCount + 1
        else
            --DEBUG(L"  Objective #"..objective..L" has no data.")
            WindowSetShowing( objectiveWindowString, false )
        end     

    end     

    if (objectiveCount > 0)
    then
        WindowSetShowing( "EA_Window_PublicQuestTracker", true )
    else
        WindowSetShowing( "EA_Window_PublicQuestTracker", false )
    end
        
    -- I have a bug somewhere in here that's causing the window not to be sized correctly the first time through
    EA_Window_PublicQuestTracker.UpdateMainWindowSize()
end

function EA_Window_PublicQuestTracker.UpdateQuestVisibility()
    if ( #DataUtils.activeObjectivesData == 0) or 
         ( (PQData.currentState ~= PQData.STATE_CLEAR) and
         ( GameData.PQData.id == DataUtils.activeObjectivesData[GameData.ActiveObjectives.updatedObjectiveIndex].id )) or
         (not DataUtils.activeObjectivesData[GameData.ActiveObjectives.updatedObjectiveIndex].isPublicQuest)
    then
        WindowSetShowing("EA_Window_PublicQuestTrackerObjective1", false)
        WindowSetShowing("EA_Window_PublicQuestTrackerObjective2", false)
    else
        if (#DataUtils.activeObjectivesData > 2)
        then
            ERROR(L""..#DataUtils.activeObjectivesData..L" objectives detected, Public Quest Tracker will only display the first two.")
        end
        
        WindowSetShowing("EA_Window_PublicQuestTrackerObjective1", true)

        if (#DataUtils.activeObjectivesData > 1)
        then
            WindowSetShowing("EA_Window_PublicQuestTrackerObjective2", true)
        end
    end
    
    EA_Window_PublicQuestTracker.UpdateMainWindowSize()
end

function EA_Window_PublicQuestTracker.UpdateMainWindowSize()

    local height = 0
    local mainHeight = 0
    
    if WindowGetShowing("EA_Window_PublicQuestTracker")
    then
    
        -- Influence Bar.
        local _, influenceY = WindowGetDimensions( "EA_Window_PublicQuestTrackerInfluenceBar" )
        height = height + influenceY
        
        -- Location Bar.
        local _, locationY = WindowGetDimensions( "EA_Window_PublicQuestTrackerLocation" )
        height = height + locationY + 25 -- 25 is the anchor offset between the location bar and objective1 window
        
        -- Main Windows.
        for objective = 1, EA_Window_PublicQuestTracker.NUM_OBJECTIVES
        do
            local objectiveWindowName = "EA_Window_PublicQuestTrackerObjective"..objective
            local objectiveWindowHeight = 0

            if WindowGetShowing(objectiveWindowName)
            then

                -- add the anchor offset between objectives
                if( objective > 1 )
                then
                    height = height + 5 -- anchor offset between Objective(N) and Objective(N+1)
                end
                
                -- Quests    
                for questIndex = 1, EA_Window_PublicQuestTracker.NUM_QUESTS
                do
                    -- Only update the window when it actually contains data
                    local questWindowHeight = 0
                    local questWindowName = objectiveWindowName.."Quest"..questIndex
                    if( WindowGetShowing( questWindowName ) == true )
                    then
                        local _, questLabelY   = LabelGetTextDimensions( questWindowName.."Label" )
                        local conditionsHeight = EA_Window_PublicQuestTracker.UpdateConditionsSize( questWindowName.."Data" )
                        
                        questWindowHeight = questLabelY + conditionsHeight + 1 -- 1 is the anchor offset between the quest label and quest conditions
                                                                               -- on a EA_Window_PublicQuestTrackerQuestCluster

                        WindowSetDimensions( questWindowName.."Data", EA_Window_PublicQuestTracker.WIDTH, conditionsHeight  )
                        WindowSetDimensions( questWindowName,         EA_Window_PublicQuestTracker.WIDTH, questWindowHeight ) 
                    else
                        WindowSetDimensions( questWindowName.."Data", EA_Window_PublicQuestTracker.WIDTH, 0 ) 
                        WindowSetDimensions( questWindowName,         EA_Window_PublicQuestTracker.WIDTH, 0 ) 
                    end
                    
                    objectiveWindowHeight = objectiveWindowHeight + questWindowHeight
                end
                
                -- Opt out window
                local _, optOutY = WindowGetDimensions( objectiveWindowName.."OptOutButton"  )
                objectiveWindowHeight = objectiveWindowHeight + optOutY + 8 -- 8 is the anchor offset between the quests and the opt out window
            end

            WindowSetDimensions( objectiveWindowName, EA_Window_PublicQuestTracker.WIDTH, objectiveWindowHeight )
            mainHeight = mainHeight + objectiveWindowHeight
        end

    end
    
    height = height + mainHeight
    WindowSetDimensions( "EA_Window_PublicQuestTracker", EA_Window_PublicQuestTracker.WIDTH, height )
    
end

function EA_Window_PublicQuestTracker.UpdateConditionsSize( dataWindow )
    -- Resize on Conditions
    local conditionHeight = 0
    for condition = 1, EA_Window_PublicQuestTracker.NUM_CONDITION_COUNTERS
    do
        local windowName = dataWindow.."Condition"..condition
        local nameWindowName = windowName.."Name"
        if( WindowGetShowing(windowName) == true )
        then
            local _, conditionTextHeight = LabelGetTextDimensions( nameWindowName )
            WindowSetDimensions( nameWindowName, EA_Window_PublicQuestTracker.CONDITION_NAME_WIDTH, conditionTextHeight ) 
            WindowSetDimensions( windowName,     EA_Window_PublicQuestTracker.WIDTH,                conditionTextHeight ) 
            conditionHeight = conditionHeight + conditionTextHeight
        else
            WindowSetDimensions( nameWindowName, EA_Window_PublicQuestTracker.CONDITION_NAME_WIDTH, 0 ) 
            WindowSetDimensions( windowName,     EA_Window_PublicQuestTracker.WIDTH,                0 ) 
        end
    end
    
    return conditionHeight
end

-- Updates the Quest & Condition Data for an Objective
function EA_Window_PublicQuestTracker.UpdateTracker( objective )     
   
    -- DEBUG(L"EA_Window_PublicQuestTracker.UpdateTracker("..objective..L"): #"..GameData.ActiveObjectives[objective].id..L" '"..GameData.ActiveObjectives[objective].name..L"' control = "..GameData.ActiveObjectives[objective].curControlPoints )
    if (not ((objective == 1) or (objective == 2)))
    then
        DisplayObjectiveOutOfRangeError(objective)
        return -- This should never happen
    end
    
    local objectiveData = DataUtils.activeObjectivesData[objective]
    local objectiveWindowString = "EA_Window_PublicQuestTrackerObjective"..objective

    -- If this index isn't used or it is a battlefield objective, hide the objective tracker
    WindowSetShowing( objectiveWindowString, objectiveData ~= nil and not objectiveData.isBattlefieldObjective )
    
    -- nothing else to do
    if ( objectiveData == nil ) or
       ( objectiveData.isBattlefieldObjective )
    then
        return
    end    
    
    -- set opt out flag
    ButtonSetPressedFlag( objectiveWindowString.."OptOutButton", objectiveData.optedOutForLoot )

    local displayData = EA_Window_PublicQuestTracker.currentData[objective]
    
    -- Name and Difficulty
    local difficultyColor = TrackerUtils.GetDifficultyColor( objectiveData.difficulty )
    LabelSetTextColor( objectiveWindowString.."Quest1Label", difficultyColor.r, difficultyColor.g, difficultyColor.b )
    
    -- Quests
    for questIndex = 1, EA_Window_PublicQuestTracker.NUM_QUESTS
    do
        -- DEBUG(L"Made it through 02")
        local questData = objectiveData.Quest[questIndex]
        local questWindowString = objectiveWindowString.."Quest"..questIndex
        
        if ( questData ~= nil )
        then
            -- DEBUG(L"Made it through 03")    
            
            WindowSetShowing( questWindowString, true )
            --DEBUG(L"  Quest #"..questIndex..L" '"..GameData.ActiveObjectives[objective].Quest[questIndex].name..L"'")
            
            -- Execute special layout for quests past the first one if the realm is the same as the
            --   previous quest's realm.
            -- TODO: Fix this so that the server can send the list of quests with various realms' quests interleaved
            local realmIsSameAsPrevious = false
            if( questIndex > 1 )
            then 
                realmIsSameAsPrevious = (questData.availableRealm == 0) or
                                        (questData.availableRealm == 
                                        DataUtils.activeObjectivesData[objective].Quest[questIndex - 1].availableRealm)
            end
            
            local useOrForName = realmIsSameAsPrevious

            -- Name
            local name = L""
            if (useOrForName)
            then
                name = GetString(StringTables.Default.LABEL_ALTERNATE_QUEST_CHOICE_PREFIX )
            elseif (questData.availableRealm ~= GameData.Player.realm)
            then
                if (questData.availableRealm == GameData.Realm.ORDER)
                then
                    name = GetString(StringTables.Default.LABEL_ORDER)
                elseif (questData.availableRealm == GameData.Realm.DESTRUCTION)
                then
                    name = GetString(StringTables.Default.LABEL_DESTRUCTION)
                else
                    name = DataUtils.activeObjectivesData[objective].name
                end
                name = name..L" - "..DataUtils.activeObjectivesData[objective].Quest[questIndex].name
            else
                name = DataUtils.activeObjectivesData[objective].name
                name = name..L" - "..DataUtils.activeObjectivesData[objective].Quest[questIndex].name
                
                local difficultyText = TrackerUtils.GetDifficultyText( objectiveData.difficulty )
                name = name..L" ("..difficultyText..L")"
            end
            -- DEBUG(L"Made it through 04")
            LabelSetText(questWindowString.."Label", name )
            --DEBUG(L"  Quest #"..questIndex..L" '"..name..L"' with dimensions: x="..x..L", y="..y )

            EA_Window_PublicQuestTracker.UpdateQuestTimer()          
          
            -- Conditions
            for index, data in ipairs(questData.conditions)
            do
                local conditionName = data.name
                local curCounter    = data.curCounter
                local maxCounter    = data.maxCounter
                local isFailureCondition = data.failureCondition
                
                local nameLabel    = questWindowString.."DataCondition"..index.."Name"
                local counterLabel = questWindowString.."DataCondition"..index.."Counter"
                local typeImage    = questWindowString.."DataCondition"..index.."Type"

                -- Only show the conditions if conditionName is not empty
                if( conditionName ~= L"" )
                then
                -- DEBUG(L"Made it through 06 - conditions")
                    
                    if( maxCounter > 0 )
                    then
                        LabelSetText( nameLabel, conditionName..L" - " )
                        LabelSetText( counterLabel, L""..curCounter..L"/"..maxCounter )

                        if( curCounter == maxCounter)
                        then
                            LabelSetTextColor(counterLabel, CompleteCounterColor.r, CompleteCounterColor.g, CompleteCounterColor.b )
                            LabelSetTextColor(nameLabel,    CompleteCounterColor.r, CompleteCounterColor.g, CompleteCounterColor.b )
                        else
                            LabelSetTextColor(counterLabel, IncompleteCounterColor.r, IncompleteCounterColor.g, IncompleteCounterColor.b)
                            LabelSetTextColor(nameLabel,    IncompleteCounterColor.r, IncompleteCounterColor.g, IncompleteCounterColor.b)
                        end         
                        
                        --DEBUG(L"    Condition #"..condition..L": "..curCounter..L" of "..maxCounter..L" counters.")
                    else
                        LabelSetText( nameLabel, conditionName )            
                        LabelSetText( counterLabel, L"" )
                    end
                             
                    WindowSetShowing(questWindowString.."DataCondition"..index, true )
                else
                    LabelSetText( nameLabel, L"" )
                    LabelSetText( counterLabel, L"" )
                    WindowSetShowing(questWindowString.."DataCondition"..index, false)
                end
                
                if (isFailureCondition)
                then
                    DynamicImageSetTextureSlice(typeImage, "PQ-Failure-Condition")
                else
                    DynamicImageSetTextureSlice(typeImage, "PQ-Success-Condition")
                end
                
            end
            
            for index = #questData.conditions + 1, EA_Window_PublicQuestTracker.NUM_CONDITION_COUNTERS
            do
                local nameLabel    = questWindowString.."DataCondition"..index.."Name"
                local counterLabel = questWindowString.."DataCondition"..index.."Counter"

                LabelSetText( nameLabel, L"" )
                LabelSetText( counterLabel, L"" )
                WindowSetShowing(questWindowString.."DataCondition"..index, false)
            end
                       
        else
            WindowSetShowing(questWindowString, false)
        end
        
    end        
    -- DEBUG(L"Made it through 07 - exiting")

end


function EA_Window_PublicQuestTracker.MouseOverQuest()

    local objective  = WindowGetId(WindowGetParent(SystemData.ActiveWindow.name))
    local questIndex = WindowGetId(SystemData.ActiveWindow.name)
    -- DEBUG(L"EA_Window_PublicQuestTracker.MouseOverQuest - ActiveObjective Index = "..objective..L", quest index = "..questIndex )

    if (DataUtils.activeObjectivesData[objective] == nil)
    then
        return
    elseif ( DataUtils.activeObjectivesData[objective].Quest[questIndex] == nil )
    then
        return
    end
    
    local objectiveData = DataUtils.activeObjectivesData[objective]
    local questData     = objectiveData.Quest[questIndex]

    Tooltips.CreateTextOnlyTooltip( SystemData.ActiveWindow.name )    
    local row = 1
    local column = 1

    -- Name
    local text = questData.name
    Tooltips.SetTooltipFont( row, column, "font_default_sub_heading", WindowUtils.FONT_DEFAULT_SUB_HEADING_LINESPACING  )
    Tooltips.SetTooltipText( row, column, text )
    Tooltips.SetTooltipColor( row, column, 255, 204, 102 )
    
    -- Complete Label
    column = column + 1 
    if( questData.complete == true )
    then
        text = GetString( StringTables.Default.LABEL_COMPLETE )         
        Tooltips.SetTooltipColor( row, column, CompleteCounterColor.r, CompleteCounterColor.g, CompleteCounterColor.b)
        Tooltips.SetTooltipText( row, column, text )
    end
    row = row + 1
    column = 1
    
    -- Objective Label
    text = GetString( StringTables.Default.LABEL_PUBLIC_QUEST ) 
    -- Difficulty
    local difficultyText = TrackerUtils.GetDifficultyText( objectiveData.difficulty )
    text = text..L" ("..difficultyText..L")"
    Tooltips.SetTooltipText( row, column, text )
    Tooltips.SetTooltipColor( row, column, 100, 100, 100)
    
    row = row + 1
    
    -- Text
    local text = questData.desc
    Tooltips.SetTooltipText( row, column, text )
    row = row + 1
    column = 1
    
    -- Difficulty help
    text = TrackerUtils.GetDifficultyHelpText( objectiveData.difficulty )
    local color = TrackerUtils.GetDifficultyColor( objectiveData.difficulty )
    Tooltips.SetTooltipText( row, column, text )
    Tooltips.SetTooltipColor( row, column, color.r, color.g, color.b )
    

    Tooltips.Finalize()
    Tooltips.AnchorTooltip( Tooltips.ANCHOR_WINDOW_LEFT )   
end

----------------------------------------------------------------
-- Influence Bar
----------------------------------------------------------------

function EA_Window_PublicQuestTracker.OnAreaChange()
    EA_Window_PublicQuestTracker.UpdateInfluenceBar()
    EA_Window_PublicQuestTracker.UpdateLocation()
end

function EA_Window_PublicQuestTracker.OnZoneChange()
    EA_Window_PublicQuestTracker.UpdateFullList()
    EA_Window_PublicQuestTracker.UpdateInfluenceBar()
    EA_Window_PublicQuestTracker.UpdateLocation()
end

function EA_Window_PublicQuestTracker.OnPlayerInfluenceUpdated()
    EA_Window_PublicQuestTracker.UpdateInfluenceBar()
end

function EA_Window_PublicQuestTracker.UpdateInfluenceBar()
    local showBar = DataUtils.UpdateInfluenceBar( "EA_Window_PublicQuestTrackerInfluenceBarFill", EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID() )
    
    local infID, hasPQButNoInfluence = EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID()
    
    -- Hide the location and the influence if we are not in an area that has influence
    WindowSetShowing( "EA_Window_PublicQuestTrackerLocation", not hasPQButNoInfluence )
    WindowSetShowing( "EA_Window_PublicQuestTrackerInfluenceBar", not hasPQButNoInfluence )
    
    -- Show or hide the entire window depending on whether we're in an influence area or a PQ area without influence.
    WindowSetShowing("EA_Window_PublicQuestTracker", showBar or hasPQButNoInfluence)
    EA_Window_PublicQuestTracker.UpdateMainWindowSize()
end

function EA_Window_PublicQuestTracker.OnMouseOverInfluenceBar()

    local influenceData = DataUtils.GetInfluenceData( EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID())
    if( influenceData ~= nil )
    then
        -- Fix for rogue entries
        if( influenceData.zoneNum == 0 and influenceData.zoneAreaNum == 0 )
        then
            return
        end
        
        local zoneName  = GetZoneName( influenceData.zoneNum )
        local areaName = GetZoneAreaName(  influenceData.zoneNum, influenceData.zoneAreaNum )
        
        local line1 = GetString( StringTables.Default.LABEL_AREA_INFLUENCE )
        local stringIndex = StringTables.Default.TEXT_PQ_TRACKER_INFLUENCE_BAR
        if( influenceData.isRvRInfluence )
        then
            stringIndex = StringTables.Default.TEXT_PQ_TRACKER_INFLUENCE_RVR_BAR
        end
        local line2 = GetStringFormat( stringIndex, { influenceData.npcName, areaName, zoneName, influenceData.npcName } )
        local actionText = GetString( StringTables.Default.TEXT_CLICK_VIEW_REWARDS )    
        
        Tooltips.CreateTextOnlyTooltip( SystemData.ActiveWindow.name )
        Tooltips.SetTooltipText( 1, 1, line1)
        Tooltips.SetTooltipColorDef( 1, 1, Tooltips.COLOR_HEADING )
        Tooltips.SetTooltipText( 2, 1, line2)
        
        Tooltips.SetTooltipActionText( actionText)
        
        Tooltips.Finalize()
        Tooltips.AnchorTooltip( Tooltips.ANCHOR_WINDOW_LEFT )   
    end
end

function EA_Window_PublicQuestTracker.OnClickInfluenceBar()
    
    local influenceData = DataUtils.GetInfluenceData( EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID() )

    if( influenceData ~= nil ) then
        -- Fix for rogue entries
        if( influenceData.zoneNum == 0 and influenceData.zoneAreaNum == 0 )
        then
            return
        end
    
        -- Open the tome to the link
        TomeWindow.OpenTomeToEntry( influenceData.tomeSection, influenceData.tomeEntry )
    end
    
end

function EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID()

    local areaData = GetAreaData()
    
    if( areaData == nil )
    then
        -- DEBUG(L"[EA_Window_PublicQuestTracker.GetLocalAreaInfluenceID] AreaData returned nil")
        return nil, false
    end
    
    local hasPQButNoInfluence = false
    for key, value in ipairs( areaData )
    do
        -- These should match the data that was retrived from war_interface::LuaGetAreaData
        if (value.influenceID ~= 0)
        then
            -- Return whatever value.hasPQButNoInfluence is
            return value.influenceID, value.hasPQButNoInfluence
        elseif( value.hasPQButNoInfluence )
        then
            -- If any of the areas we are in have a PQ but no influence we want this to be true
            hasPQButNoInfluence = true
        end
    end
    
    return nil, hasPQButNoInfluence
end


function EA_Window_PublicQuestTracker.ToggleOptOut()
 
    local index = WindowGetId( SystemData.ActiveWindow.name )

    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end
    
    local optedOutForLootRoll = ButtonGetPressedFlag( SystemData.ActiveWindow.name )
    TrackerUtils.OnMouseOverOptOut()
    
    if( EA_Window_PublicQuestTracker.currentData[index] )
    then
        local objectiveId = EA_Window_PublicQuestTracker.currentData[index].objectiveId 
        LootRollOptOut(objectiveId, optedOutForLootRoll) 
    end
    
end

function EA_Window_PublicQuestTracker.OnQuestOptOut(index, optOut)
   
    if (not ((index == 1) or (index == 2)))
    then
        DisplayObjectiveOutOfRangeError(index)
        return -- This should never happen
    end
    
    ButtonSetPressedFlag( "EA_Window_PublicQuestTrackerObjective"..index.."OptOutButton", optOut )

    DataUtils.activeObjectivesData[index].optedOutForLoot = optOut
end
